<template>
  <div></div>
</template>

<script>
import * as THREE from 'three'
import gsap from 'gsap'
import { beautifulRandomColor } from '@/utils/color'

export default {
  data () {
    return {
      myTween: null,
      mouseX: 0,
      mouseY: 0,
      particles: null,
      camera: null,
      renderer: null,
      scene: null,
      canvasDiv: null
    }
  },
  mounted () {
    this.scene = new THREE.Scene()
    this.canvasDiv = document.getElementById('web-home-canvas-bg')
    window.addEventListener('mousemove', this.mousemove, false)
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)

    this.renderer = new THREE.WebGLRenderer({ alpha: true })
    this.renderer.setClearAlpha(0)
    this.renderer.setSize(window.innerWidth, window.innerHeight)
    this.renderer.domElement.id = 'home-animation-01-canvas'
    this.canvasDiv.appendChild(this.renderer.domElement)

    window.addEventListener('resize', this.resize)

    const distance = Math.min(200, window.innerWidth / 4)
    const geometry = new THREE.Geometry()

    for (let i = 0; i < 1600; i++) {
      const vertex = new THREE.Vector3()

      const theta = THREE.Math.randFloatSpread(360)
      const phi = THREE.Math.randFloatSpread(360)

      vertex.x = distance * Math.sin(theta) * Math.cos(phi)
      vertex.y = distance * Math.sin(theta) * Math.sin(phi)
      vertex.z = distance * Math.cos(theta)

      geometry.vertices.push(vertex)
    }
    this.particles = new THREE.Points(geometry, new THREE.PointsMaterial({ color: beautifulRandomColor(), size: 2 }))
    this.particles.boundingSphere = 50

    const renderingParent = new THREE.Group()
    renderingParent.add(this.particles)

    const resizeContainer = new THREE.Group()
    resizeContainer.add(renderingParent)
    this.scene.add(resizeContainer)

    this.camera.position.z = 400

    this.animate()

    // Scaling animation
    const animProps = { scale: 1, xRot: 0, yRot: 0 }
    gsap.to(animProps, {
      duration: 10,
      scale: 1.3,
      repeat: -1,
      yoyo: true,
      ease: 'sine',
      onUpdate () {
        renderingParent.scale.set(animProps.scale, animProps.scale, animProps.scale)
      }
    })

    gsap.to(animProps, {
      duration: 120,
      xRot: Math.PI * 2,
      yRot: Math.PI * 4,
      repeat: -1,
      yoyo: true,
      ease: 'none',
      onUpdate () {
        renderingParent.rotation.set(animProps.xRot, animProps.yRot, 0)
      }
    })
  },
  methods: {
    mousemove (event) {
      if (!this.particles) { return }
      if (this.myTween) { this.myTween.kill() }
      this.mouseX = (event.clientX / window.innerWidth) * 2 - 1
      this.mouseY = -(event.clientY / window.innerHeight) * 2 + 1
      this.myTween = gsap.to(this.particles.rotation, { duration: 0.1, x: this.mouseY * -1, y: this.mouseX })
    },
    resize () {
      this.camera.aspect = window.innerWidth / window.innerHeight
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
    },
    animate () {
      requestAnimationFrame(this.animate)
      this.renderer.render(this.scene, this.camera)
    }
  },
  beforeDestroy () {
    window.removeEventListener('mousemove', this.mousemove)
    window.removeEventListener('resize', this.resize)
    const homeAnimationDom = document.getElementById('web-home-canvas-bg')
    const canvasDom = document.getElementById('home-animation-01-canvas')
    homeAnimationDom.removeChild(canvasDom)
  }
}
</script>

<style scoped></style>
